package org.monster.context.core.request;

import org.monster.context.core.Constants;
import org.monster.context.core.communicator.HttpHeader;
import org.monster.context.core.dispatcher.ApplicationDispatcher;
import org.monster.context.core.parameter.HttpResponse;
import org.monster.context.core.parameter.Parameter;
import org.monster.context.util.URIUtils;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Http请求
 *
 * @author Monster
 */
public class HttpRequest implements HttpServletRequest, ServletRequest {

    /**
     * 日志器
     */
    private static final Logger logger = Logger.getLogger(HttpRequest.class.getName());
    /**
     * uri
     */
    private String uri;
    /**
     * 方法
     */
    private String method;
    /**
     * 协议
     */
    private String protocol;
    /**
     * 上下文
     */
    private String contextPath;
    /**
     * 响应
     */
    private HttpResponse response;
    /**
     * 输入流
     */
    private InputStream input;
    /**
     * 请求uri
     */
    private String requestURI;
    /**
     * 服务者路径
     */
    private String servletPath;
    /**
     * 请求信息
     */
    private String headerInfo = null;
    /**
     * 请求url
     */
    private StringBuffer requestURL;
    /**
     * 头 键值
     */
    private Map<String, HttpHeader> headers = new HashMap<>();
    /**
     * 参数 键值
     */
    private Map<String, Parameter> parameters = new HashMap<>();
    /**
     * 属性 键值
     */
    private Map<String, Object> attributes = new HashMap<>();
    /**
     * 内容长度
     */
    private int contentLength;
    /**
     * 服务者端口
     */
    private int serverPort;
    /**
     * 派遣类型
     */
    private DispatcherType DispatcherType;
    /**
     * 字符串编码
     */
    private String characterEncoding;
    /**
     * 内容类型
     */
    private String contentType;

    /**
     * 构造方法
     *
     * @param input 输入流
     */
    public HttpRequest(InputStream input) {
        this.input = input;
    }

    /**
     * 获取 响应
     *
     * @return 响应
     */
    public HttpResponse getResponse() {
        return response;
    }

    /**
     * 设置 响应
     *
     * @param response 响应
     */
    public void setResponse(HttpResponse response) {
        this.response = response;
    }

    /**
     * 获取 输入
     *
     * @return 输入
     */
    public InputStream getInput() {
        return input;
    }

    /**
     * 设置
     *
     * @param input 输入
     */
    public void setInput(InputStream input) {
        this.input = input;
    }

    /**
     * 获取 请求url
     *
     * @param url url
     * @return
     */
    public String getRequestURL(String url) {
        return getRequestURL().toString();
    }

    /**
     * 获取 方法
     *
     * @return 方法
     */
    @Override
    public String getMethod() {
        return method;
    }

    /**
     * 设置 方法
     *
     * @param method 方法
     */
    public void setMethod(String method) {
        this.method = method;
    }

    /**
     * 获取 uri
     *
     * @return uri
     */
    public String getURI() {
        return getUri();
    }

    /**
     * 设置 uri
     *
     * @param uri uri
     */
    public void setURI(String uri) {
        this.setUri(uri);
    }

    /**
     * 获取 请求url
     *
     * @return 请求url
     */
    @Override
    public StringBuffer getRequestURL() {
        return requestURL;
    }

    /**
     * @param requestURL the requestURL to set
     */
    public void setRequestURL(StringBuffer requestURL) {
        this.requestURL = requestURL;
    }

    /**
     * 设置 请求url
     *
     * @param requestURL 请求url
     */
    public void setRequestURL(String requestURL) {
        this.setRequestURL(new StringBuffer(requestURL));
    }

    /**
     * 获取 请求uri
     *
     * @return 请求uri
     */
    @Override
    public String getRequestURI() {
        return requestURI;
    }

    /**
     * 设置 请求uri
     *
     * @param requestURI 请求URI
     */
    public void setRequestURI(String requestURI) {
        this.requestURI = requestURI;
    }

    /**
     * 获取 协议
     *
     * @return 协议
     */
    @Override
    public String getProtocol() {
        return protocol;
    }

    /**
     * 设置 协议
     *
     * @param protocol 协议
     */
    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }

    /**
     * 获取 头信息
     *
     * @return 头信息
     */
    public String getHeaderInfo() {
        return headerInfo;
    }

    /**
     * 设置 头信息
     *
     * @param headerInfo 头信息
     */
    public void setHeaderInfo(String headerInfo) {
        this.headerInfo = headerInfo;
    }

    /**
     * 设置 参数
     *
     * @param parameter 参数
     */
    public void setParameters(Parameter parameter) {
        getParameters().put(parameter.getName(), parameter);
    }

    /**
     * 获取 头
     *
     * @param name 名称
     * @return 头
     */
    @Override
    public String getHeader(String name) {
        String headerVal = null;
        if (getHeaders().size() > 0) {
            headerVal = getHeaders().get(name).getValue();
        }
        return headerVal;
    }

    /**
     * 添加 头
     *
     * @param header 头
     */
    public void addHeader(HttpHeader header) {
        getHeaders().put(header.getName(), header);

    }

    /**
     * 获取参数
     *
     * @param name 名称
     * @return 参数
     */
    @Override
    public String getParameter(String name) {
        String value;
        try {
            value = (getParameters().get(name)).getValue();
        } catch (Exception e) {
            value = null;
        }
        return value;
    }

    /**
     * 解析 请求
     *
     * @return 字符串
     * @throws IOException 输入输出异常
     */
    public String parseRequest() throws IOException {
        byte[] buffer = new byte[4096];
        int len;
        len = getInput().read(buffer);
        if (len != -1) {
            setHeaderInfo(new String(buffer).trim());
        }
        setContentLength(len);
        return getHeaderInfo();
    }

    /**
     * 获取URI（所有请求信息）
     *
     * @param uri uri
     * @return
     */
    public String getRequestURI(String uri) {
        int target, actual;
        target = uri.indexOf('\u0020');
        if (target != -1) {
            actual = uri.indexOf('\u0020', target + 1);
            if (actual > target) {
                uri = uri.substring(target + 1, actual);
            }
        }
        int index = uri.indexOf('?');
        if (index != -1) {
            uri = uri.substring(0, index);
        }
        return uri;
    }

    /**
     * 获取 协议
     * 通过requestURI获取Protocol
     *
     * @param uri
     * @return
     */
    public String getProtocol(String uri) {
        try {
            int index = uri.lastIndexOf('\u0020');
            if (index != -1) {
                uri = uri.substring(index, uri.length());
            }
        } catch (Exception e) {
            logger.log(Level.INFO, e.getMessage());
        }
        return uri;
    }

    /**
     * 获取 头信息
     *
     * @param name 名
     * @return 头
     */
    public String getHeaderInfo(String name) {
        String[] split = getHeaderInfo().split("\u0A00");
        for (String str : split) {
            int i = str.indexOf(name);
            if (i != -1 && str.length() > name.length() + 2) {
                setHeaderInfo(str
                        .substring(name.length() + 2, str.length() - 1));
                break;
            }
        }
        return getHeaderInfo();
    }

    /**
     * 获取 方法
     * 判断请求类型
     *
     * @param uri uri
     * @return 方法
     */
    public String getMethod(String uri) {
        if (uri != null && uri.length() > 0) {
            setMethod(uri.substring(0, 3));
            if (getMethod().equalsIgnoreCase(Constants.METHOD_GET)) {
                return Constants.METHOD_GET;
            } else if (getMethod().equalsIgnoreCase(Constants.METHOD_DOS)) {
                return Constants.METHOD_DOS;
            } else {
                setMethod(null);
            }
        }
        return Constants.METHOD_POST;
    }

    /**
     * 获取 请求派遣器
     *
     * @param name 请求派遣器
     * @return 请求派遣器
     */
    @Override
    public RequestDispatcher getRequestDispatcher(String name) {
        return new ApplicationDispatcher(name, this,
                getResponse());
    }

    /**
     * 获取 上下文路径
     *
     * @return 上下文路径
     */
    @Override
    public String getContextPath() {
        if (contextPath != null) {
            return contextPath;
        } else {
            return URIUtils.startWithURI(getRequestURI());
        }
    }

    /**
     * 设置 上下文路径
     *
     * @param contextPath 上下文路径
     */
    public void setContextPath(String contextPath) {
        this.contextPath = contextPath;
    }

    /**
     * 获取 服务者路径
     *
     * @return 服务者路径
     */
    @Override
    public String getServletPath() {
        if (servletPath != null) {
            return servletPath;
        } else {
            return URIUtils.allEndsWithURI(getRequestURI());
        }
    }

    /**
     * 设置 服务者路径
     *
     * @param servletPath 服务者路径
     */
    public void setServletPath(String servletPath) {
        this.servletPath = servletPath;
    }

    /**
     * 获取 内容长度
     *
     * @return 内容长度
     */
    @Override
    public int getContentLength() {
        return contentLength;
    }

    /**
     * 设置 内容长度
     *
     * @param length 长度
     */
    public void setContentLength(int length) {
        contentLength = length;
    }

    /**
     * 获取 服务器端口
     *
     * @return 服务器端口
     */
    @Override
    public int getServerPort() {
        return serverPort;
    }

    /**
     * 设置 服务器端口
     *
     * @param serverPort 服务器端口
     */
    public void setServerPort(int serverPort) {
        this.serverPort = serverPort;
    }

    /**
     * 获取 派遣器类型
     *
     * @return 派遣器类型
     */
    @Override
    public DispatcherType getDispatcherType() {
        return DispatcherType;
    }

    /**
     * 设置 派遣器类型
     *
     * @param dispatcherType 派遣器类型
     */
    public void setDispatcherType(DispatcherType dispatcherType) {
        this.DispatcherType = dispatcherType;
    }

    /**
     * 获取 派遣器类型
     *
     * @return 服务器名
     */
    @Override
    public String getServerName() {
        return "Monster-1.0";
    }

    /**
     * 获取 字符串编码
     *
     * @return 字符串编码
     */
    @Override
    public String getCharacterEncoding() {
        if (characterEncoding != null) {
            return characterEncoding;
        } else {
            return "UTF-8";
        }
    }

    /**
     * 设置 字符串编码
     *
     * @param characterEncoding 字符串编码
     * @throws UnsupportedEncodingException 不支持编码异常
     */
    @Override
    public void setCharacterEncoding(String characterEncoding)
            throws UnsupportedEncodingException {
        this.characterEncoding = characterEncoding;
    }

    /**
     * 获取 内容类型
     *
     * @return 内容类型
     */
    @Override
    public String getContentType() {
        return contentType;
    }

    /**
     * 设置 内容类型
     *
     * @param contentType 内容类型
     */
    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    /**
     * 获取 属性
     *
     * @param name 名称
     * @return 属性
     */
    @Override
    public Object getAttribute(String name) {
        return getAttributes().get(name);
    }

    /**
     * 移除 属性
     *
     * @param name 名称
     */
    @Override
    public void removeAttribute(String name) {
        getAttributes().remove(name);
    }

    /**
     * 设置 属性
     *
     * @param name 名称
     * @param obj  对象
     */
    @Override
    public void setAttribute(String name, Object obj) {
        getAttributes().put(name, obj);
    }

    /**
     * 获取 异步上下文
     *
     * @return 异步上下文
     */
    @Override
    public AsyncContext getAsyncContext() {

        return null;
    }

    /**
     * 获取 属性名 列举
     *
     * @return 属性名
     */
    @Override
    public Enumeration<String> getAttributeNames() {

        return null;
    }

    /**
     * 获取 本地地址
     *
     * @return 本地地址
     */
    @Override
    public String getLocalAddr() {

        return null;
    }

    /**
     * 获取 语言环境
     *
     * @return 语言环境
     */
    @Override
    public Locale getLocale() {
        return null;
    }

    /**
     * 获取 语言环境 列举
     *
     * @return 语言环境 列举
     */
    @Override
    public Enumeration<Locale> getLocales() {

        return null;
    }

    /**
     * 获取 参数 键值
     *
     * @return 参数 键值
     */
    @Override
    public Map<String, String[]> getParameterMap() {

        return null;
    }

    /**
     * 获取 参数名 键值
     *
     * @return 参数名 键值
     */
    @Override
    public Enumeration<String> getParameterNames() {

        return null;
    }

    /**
     * 获取 真实路径
     *
     * @param url url
     * @return 真实路径
     */
    @Override
    public String getRealPath(String url) {

        return null;
    }

    /**
     * 获取 远程地址
     *
     * @return 远程地址
     */
    @Override
    public String getRemoteAddr() {

        return null;
    }

    /**
     * 获取 模式
     *
     * @return 模式
     */
    @Override
    public String getScheme() {

        return null;
    }

    /**
     * 获取 服务者上下文
     *
     * @return 服务者上下文
     */
    @Override
    public ServletContext getServletContext() {

        return null;
    }

    /**
     * 是否 异步开启过
     *
     * @return 布尔
     */
    @Override
    public boolean isAsyncStarted() {

        return false;
    }

    /**
     * 是否 异步支持
     *
     * @return 布尔
     */
    @Override
    public boolean isAsyncSupported() {

        return false;
    }

    /**
     * 是否 安全
     *
     * @return 布尔
     */
    @Override
    public boolean isSecure() {

        return false;
    }

    /**
     * 开启 异步
     *
     * @return 异步上下文
     * @throws IllegalStateException 非法状态异常
     */
    @Override
    public AsyncContext startAsync() throws IllegalStateException {

        return null;
    }

    /**
     * 开启 异步
     *
     * @param request  请求
     * @param response 响应
     * @return 异步上下文
     * @throws IllegalStateException 非法状态异常
     */
    @Override
    public AsyncContext startAsync(ServletRequest request, ServletResponse response)
            throws IllegalStateException {

        return null;
    }

    /**
     * 授权
     *
     * @param response 响应
     * @return 布尔
     * @throws IOException      输入输出异常
     * @throws ServletException 服务者异常
     */
    @Override
    public boolean authenticate(HttpServletResponse response) throws IOException,
            ServletException {

        return false;
    }

    /**
     * 获取 授权类型
     *
     * @return 授权类型
     */
    @Override
    public String getAuthType() {

        return null;
    }

    /**
     * 获取 cookie数组
     *
     * @return cookie数组
     */
    @Override
    public Cookie[] getCookies() {

        return null;
    }

    /**
     * 获取 日期头
     *
     * @param name 名称
     * @return 时间戳
     */
    @Override
    public long getDateHeader(String name) {

        return 0;
    }

    /**
     * 获取 头名称 列举
     *
     * @return 头名称 列举
     */
    @Override
    public Enumeration<String> getHeaderNames() {

        return null;
    }

    /**
     * 获取 头 列举
     *
     * @param name 名称
     * @return 头 列举
     */
    @Override
    public Enumeration<String> getHeaders(String name) {

        return null;
    }

    /**
     * 获取 初始化头
     *
     * @param name 初始化头
     * @return 初始化头
     */
    @Override
    public int getIntHeader(String name) {

        return 0;
    }

    /**
     * 获取 部分
     *
     * @param field 字段
     * @return 部分
     * @throws IOException      输入输出异常
     * @throws ServletException 服务者异常
     */
    @Override
    public Part getPart(String field) throws IOException, ServletException {

        return null;
    }

    /**
     * 获取 部分 集合
     *
     * @return 部分 集合
     * @throws IOException      输入输出异常
     * @throws ServletException 服务者异常
     */
    @Override
    public Collection<Part> getParts() throws IOException, ServletException {

        return null;
    }

    /**
     * 获取 路径信息
     *
     * @return 路径信息
     */
    @Override
    public String getPathInfo() {

        return null;
    }

    /**
     * 获取 翻译过路径
     *
     * @return 翻译过路径
     */
    @Override
    public String getPathTranslated() {

        return null;
    }

    /**
     * 获取 请求字符串
     *
     * @return 请求字符串
     */
    @Override
    public String getQueryString() {

        return null;
    }

    /**
     * 获取 远程用户
     *
     * @return 远程用户
     */
    @Override
    public String getRemoteUser() {

        return null;
    }

    /**
     * 获取 请求会话辨识
     *
     * @return 请求会话辨识
     */
    @Override
    public String getRequestedSessionId() {

        return null;
    }

    /**
     * 请求 会话
     *
     * @return 会话
     */
    @Override
    public HttpSession getSession() {

        return null;
    }

    /**
     * 获取 会话
     *
     * @param b 布尔
     * @return 会话
     */
    @Override
    public HttpSession getSession(boolean b) {

        return null;
    }

    /**
     * 获取 首要用户
     *
     * @return 首要用户
     */
    @Override
    public Principal getUserPrincipal() {

        return null;
    }

    /**
     * 是否 来自cookie请求会话辨识
     *
     * @return 布尔
     */
    @Override
    public boolean isRequestedSessionIdFromCookie() {

        return false;
    }

    /**
     * 是否 来自url请求会话
     *
     * @return 布尔
     */
    @Override
    public boolean isRequestedSessionIdFromURL() {

        return false;
    }

    /**
     * 是否 来自url请求会话
     *
     * @return 布尔
     */
    @Override
    public boolean isRequestedSessionIdFromUrl() {

        return false;
    }

    /**
     * 是否 请求会话辨识有效
     *
     * @return 布尔
     */
    @Override
    public boolean isRequestedSessionIdValid() {

        return false;
    }

    /**
     * 是否 用户在角色
     *
     * @param user 用户
     * @return 布尔
     */
    @Override
    public boolean isUserInRole(String user) {

        return false;
    }

    /**
     * 登录
     *
     * @param user     用户
     * @param password 密码
     * @throws ServletException 服务者异常
     */
    @Override
    public void login(String user, String password) throws ServletException {


    }

    /**
     * 退出
     *
     * @throws ServletException 服务者异常
     */
    @Override
    public void logout() throws ServletException {


    }

    /**
     * 获取 服务者输入流
     *
     * @return 服务者输入流
     * @throws IOException 输入输出异常
     */
    @Override
    public ServletInputStream getInputStream() throws IOException {

        return null;
    }

    /**
     * 获取 本地名
     *
     * @return 本地名
     */
    @Override
    public String getLocalName() {

        return null;
    }

    /**
     * 获取 本地端口
     *
     * @return 本地端口
     */
    @Override
    public int getLocalPort() {

        return 0;
    }

    /**
     * 获取 参数 数组
     *
     * @param name 名称
     * @return 参数 数组
     */
    @Override
    public String[] getParameterValues(String name) {

        return null;
    }

    /**
     * 获取 缓冲器阅读器
     *
     * @return 缓冲器阅读器
     * @throws IOException 输入输出异常
     */
    @Override
    public BufferedReader getReader() throws IOException {

        return null;
    }

    /**
     * 获取 远程主机
     *
     * @return 远程主机
     */
    @Override
    public String getRemoteHost() {

        return null;
    }

    /**
     * 获取 远程端口
     *
     * @return 远程端口
     */
    @Override
    public int getRemotePort() {

        return 0;
    }

    /**
     * 获取 uri
     *
     * @return uri
     */
    public String getUri() {
        return uri;
    }

    /**
     * 设置 uri
     *
     * @param uri uri
     */
    public void setUri(String uri) {
        this.uri = uri;
    }

    /**
     * 获取 头 键值
     *
     * @return 头 键值
     */
    public Map<String, HttpHeader> getHeaders() {
        return headers;
    }

    /**
     * 设置 头 键值
     *
     * @param headers 头 键值
     */
    public void setHeaders(Map<String, HttpHeader> headers) {
        this.headers = headers;
    }

    /**
     * 获取 参数 键值
     *
     * @return 参数 键值
     */
    public Map<String, Parameter> getParameters() {
        return parameters;
    }

    /**
     * 设置 参数 键值
     *
     * @param parameters 参数 键值
     */
    public void setParameters(Map<String, Parameter> parameters) {
        this.parameters = parameters;
    }

    /**
     * 获取 属性 键值
     *
     * @return 属性 键值
     */
    public Map<String, Object> getAttributes() {
        return attributes;
    }

    /**
     * 设置 属性 键值
     *
     * @param attributes 属性 键值
     */
    public void setAttributes(Map<String, Object> attributes) {
        this.attributes = attributes;
    }

}
